/*
 * @Author: your name
 * @Date: 2021-01-04 11:09:04
 * @LastEditTime: 2021-03-15 15:26:48
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \relearnJS\interview\array\数组去重.js
 */
const arr = [1, 2, 2, 3, 3, 3, 1, 2, 1],
    {
        log
    } = console
// 1. Set
// [...new Set(arr)]
// Array.from(new Set(arr))
// ! 对象不去重

// 2. reduce
// ! 对象和NaN不去重
let uniqueByReduce = arr => {
    return arr.sort().reduce((pre, cur) => {
        if (pre.length === 0 || pre[pre.length - 1] !== cur) {
            pre.push(cur)
        }
        return pre
    }, [])
}
log('reduce:\t', uniqueByReduce(arr))

// 3. filter
// ! 对象不去重，NaN被忽略掉
let uniqueByFilter = arr => {
    return arr.filter((el, index, array) => {
        // 运用 indexOf 查找第一个匹配元素的规则，规避掉后面重复的元素
        return array.indexOf(el) === index
    })
}
log('filter:\t', uniqueByFilter(arr))

// 4. 双层 for 循环 + splice
// ! 对象和NaN不去重
let uniqueByForAndSplice = arr => {
    let len = arr.length
    arr.sort()
    for (let i = 0; i < len; i++) {
        for (let j = i + 1; j < len; j++) {
            if (arr[i] === arr[j]) {
                arr.splice(j, 1)
                len--
                j--
            }
        }
    }
    return arr
}
log('splice:\t', uniqueByForAndSplice(arr))

// 5. 双层 for 循环
// ! 对象和NaN不去重
let uniqueByDoubleForLoop = arr => {
    var res = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        for (var j = 0, reslen = res.length; j < reslen; j++) {
            if (arr[i] === arr[j]) break;
        }
        if (j === reslen) {
            res.push(arr[j])
        }
    }
    return res;
}
log('2for:\t', uniqueByDoubleForLoop(arr))

// 6. indexOf
// ! 对象不去重，NaN会被忽略掉
// * indexOf 底层使用 === 进行判断
let uniqueByIndexOf = arr => {
    var res = [];
    for (var i = 0, len = arr.length; i < len; i++) {
        var current = arr[i];
        if (res.indexOf(current) === -1) {
            res.push(current)
        }
    }
    return res;
}
log('indexOf:', uniqueByIndexOf(arr))

// 7. 键值对
// ! 无敌版
function uniqueOfFinal(arr) {
    var obj = {},
        myJSON_stringify = function (item) {
            return JSON.stringify(item, (key, val) => {
                if (Number.isNaN(val)) return 'NaN'
                if (typeof val === 'number' && !Number.isInteger(val)) return 'infinity'
                return val
            })
        }
    return arr.filter(v => {
        return obj.hasOwnProperty(typeof v + myJSON_stringify(v)) ? false : (obj[typeof v + myJSON_stringify(v)] = true)
    })
}